package com.feonix.common.util.xml;

import java.io.File;
import java.io.Writer;

import com.feonix.common.util.FileUtil;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import com.thoughtworks.xstream.mapper.MapperWrapper;

public class XmlObject {

	private XStream xStream = null;

	private String xmlString = null;

	public XmlObject() {
		this.xStream = new XStream(new StaxDriver() {
			public HierarchicalStreamWriter createWriter(Writer paramWriter) {
				return new PrettyPrintWriter(paramWriter) {
					private boolean b;

					public void startNode(String paramString, Class paramClass) {
						super.startNode(paramString, paramClass);
						if (paramClass == String.class)
							this.b = true;
						else
							this.b = false;
					}

					protected void writeText(QuickWriter paramQuickWriter, String paramString) {
						if (this.b) {
							paramQuickWriter.write("<![CDATA[");
							paramQuickWriter.write(paramString);
							paramQuickWriter.write("]]>");
						} else {
							paramQuickWriter.write(paramString);
						}
					}
				};
			}
		}) {
			protected MapperWrapper wrapMapper(MapperWrapper paramMapperWrapper) {
				return new MapperWrapper(paramMapperWrapper) {
					public boolean shouldSerializeMember(Class paramClass, String paramString) {
						if (paramClass == Object.class) {
							return false;
						}
						return super.shouldSerializeMember(paramClass, paramString);
					}
				};
			}
		};
		this.xStream.registerConverter(new XmlDateConverter());
		this.xStream.autodetectAnnotations(true);
	}

	/**
	 * 是否启用注释解析
	 * 
	 * @param paramBoolean
	 */
	public void setUseAnnotation(boolean paramBoolean) {
		this.xStream.autodetectAnnotations(paramBoolean);
	}

	/**
	 * 增加转换器
	 * 
	 * @param paramConverter
	 */
	public void addConverter(Converter paramConverter) {
		this.xStream.registerConverter(paramConverter);
	}

	/**
	 * 增加转换器
	 * 
	 * @param paramSingleValueConverter
	 */
	public void addConverter(SingleValueConverter paramSingleValueConverter) {
		this.xStream.registerConverter(paramSingleValueConverter);
	}

	/**
	 * 读取一个xml文件
	 * 
	 * @param paramFile
	 */
	public void read(File paramFile) {
		this.xmlString = FileUtil.readFileToString(paramFile);
	}

	/**
	 * 读取字符串
	 * 
	 * @param paramString
	 */
	public void read(String paramString) {
		this.xmlString = paramString;
	}

	/**
	 * 设置节点与obj的对应
	 * 
	 * @param paramString
	 * @param paramClass
	 */
	public void setNodeToClass(String paramString, Class<?> paramClass) {
		this.xStream.alias(paramString, paramClass);
	}

	/**
	 * 设置节点与obj属性的对应
	 * 
	 * @param paramString1
	 * @param paramClass
	 * @param paramString2
	 */
	public void setNodeToField(String paramString1, Class<?> paramClass, String paramString2) {
		this.xStream.aliasField(paramString1, paramClass, paramString2);
	}

	/**
	 * 设置节点与object的对应
	 * 
	 * @param paramString1
	 * @param paramString2
	 * @param paramClass
	 */
	public void setNodeAttrToField(String paramString1, String paramString2, Class<?> paramClass) {
		this.xStream.aliasAttribute(paramClass, paramString2, paramString1);
	}

	/**
	 * 需要忽略的字段
	 * 
	 * @param paramClass
	 * @param paramString
	 */
	public void setOmitField(Class paramClass, String paramString) {
		this.xStream.omitField(paramClass, paramString);
	}

	/**
	 * 获得object
	 * 
	 * @return
	 */
	public <T> T getObject() {
		return (T) this.xStream.fromXML(this.xmlString);
	}

	/**
	 * object转xml
	 * 
	 * @param paramObject
	 * @return
	 */
	public String toXml(Object paramObject) {
		return this.xStream.toXML(paramObject);
	}

}
